package main
import(
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"os"
)

//判断文件是否存在
func PathExists(path string)(bool,error){
	_,err := os.Stat(path)
	if err == nil{//文件或者目录存在
		return true,nil
	}
	if os.IsNotExist(err) {
		return false,nil
	}
	return false,err
}

//拷贝文件到另外一个目录
func CopyFile(dstFileName string,srcFileName string)(written int64 ,err error){
	//读取文件
	srcFile,err := os.Open(srcFileName)
	if(err != nil){
		fmt.Println("文件打开错误！",err)
	}
	//获取reader
	reader := bufio.NewReader(srcFile)
	defer srcFile.Close()
	//获取writer
	dstFile,err := os.OpenFile(dstFileName , os.O_WRONLY | os.O_CREATE , 0666)
	if err != nil {
		fmt.Println("文件打开错误",err)
	}
	defer dstFile.Close()
	writer := bufio.NewWriter(dstFile)
	return io.Copy(writer, reader)
}

//定义结构体，保存统计结果
type CharCount struct{
	ChCount int //英文
	NumCount int //数字
	SpaceCount int //空格
	OtherCount int //其他
}

func main(){
	//文件开启
	file , err := os.Open("test.txt")
	if err != nil{
		fmt.Print(err)
	}else{
		fmt.Print(file)
	}
	//文件关闭
	//err = file.Close()
	//if err != nil {
	//	fmt.Println("文件关闭失败！",err)
	//}else{
	//	fmt.Println("文件关闭成功！")
	//}
	defer  file.Close() //及时关闭file句柄

	//创建一个 *Reader  ，带缓冲
	reader := bufio.NewReader(file)
	//循环读取文件内容
	for {
		str,err := reader.ReadString('\n') //读到一个换行符就结束
		if err == io.EOF{ //表示读取到文件末尾
			break
		}
		fmt.Print(str)
	}
	fmt.Println("文件读取结束...")

	//一次性读取整个文件 写入文件
	allStr,err := ioutil.ReadFile("test.txt") //不需要关闭文件
	if err != nil{
		fmt.Println("文件读取错误，",err)
	}else{
		fmt.Println(string(allStr))
		e := ioutil.WriteFile("ts.txt",allStr,0666)
		if(e != nil){
			fmt.Println("文件写入失败！",e)
		}else{
			fmt.Println("文件写入成功！")
		}
	}

	//往文件里面写内容
	f := "tt.txt"
	F,err := os.OpenFile(f,os.O_CREATE | os.O_WRONLY ,0666)

	//关闭F句柄
	defer F.Close()
	if(err != nil){
		fmt.Println("文件打开错误！",err)
	}else{
		strs := "hello,Gardon\r\n"
		//写入时，使用带缓存的 *writer
		writer := bufio.NewWriter(F)
		for i := 0 ; i < 5 ; i++{
			writer.WriteString(strs)
		}
		//因为writer是带缓存，因此没有真正写入到缓存 所以写入需要调用 flush方法
		writer.Flush()
	}

	//判断文件是否存在
	_,e :=PathExists("ts.txt")
	if(e != nil){
		fmt.Println("文件不存在",e)
	}else{
		fmt.Println("文件存在")
	}

	//测试拷贝文件
	srcFile := "f:/BaiduYunDownload/6.jpg"
	dstFile := "e:/test.jpg"
	CopyFile(dstFile,srcFile)

	//判断文件中含有多少个字母，字符串，特殊字符
	testFile := "aa.txt"
	fileTest,errs := os.Open(testFile)
	if errs != nil{
		fmt.Printf("open file err =%v\n",errs)
		return
	}
	defer fileTest.Close()
	//创建count
	var count CharCount
	//创建reader
	//创建一个 *Reader  ，带缓冲
	readers := bufio.NewReader(fileTest)
	//循环读取文件内容
	for {
		str,err := readers.ReadString('\n') //读到一个换行符就结束
		if err == io.EOF{ //表示读取到文件末尾
			break
		}
		r := []rune(str)
		for _,v := range r {
			switch {//当成分支结构处理
				case v >= 'a' && v <= 'z':
					fallthrough //穿透处理
				case v >= 'A' && v <= 'Z':
					count.ChCount++
				case v == ' ' || v == '\t':
					count.SpaceCount++
				case v >= '0' && v <= '9':
					count.NumCount++
				default:
					count.OtherCount++
			}
		}
	}
	//输出统计结果
	fmt.Printf("字符的个数为=%v 数字的个数为=%v 空格的个数为=%v 其他字符个数=%v",count.ChCount,count.NumCount,count.SpaceCount,count.OtherCount)
}
